package org.achartengine.tools;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.NinePatchDrawable;
import android.util.Log;

public class LineSlider {
	private int topX, topY, bottomX, bottomY;
	private boolean touched;

	private NinePatchDrawable mPopupBoxNinePatchDrawable;

	private double lastCrossedX;

	private int xLeftLimit, xRightLimit;
	
	private boolean firstTimeTouched;

	private boolean xLeftLimitSet, xRightLimitSet;

	private String TAG = LineSlider.class.getSimpleName();
	private Paint mPaint;
	private RectF mRect;
	private Rect mScreen;

	public LineSlider(Context context) {
		this.touched = false;
		mPaint = new Paint();
		mPaint.setColor(Color.RED);
		mRect = new RectF();
		mScreen = new Rect();
		mScreen.set(0, 0, 0, 0);
		mRect.set(0, 0, 0, 0);
		xLeftLimitSet = false;
		xRightLimitSet = false;
		setCoordinates(0, 0, 0, 0);
		mPopupBoxNinePatchDrawable = (NinePatchDrawable) context.getResources().getDrawable(org.achartengine.R.drawable.pop_box);

	}

	public void setCoordinates(int topX, int topY, int bottomX, int bottomY) {
		this.topX = topX;
		this.topY = topY;
		this.bottomX = bottomX;
		this.bottomY = bottomY;
		this.xLeftLimit = 0;
		this.xRightLimit = 0;
	}

	public boolean isTouched() {
		return touched;
	}

	public void setTouched(boolean touched) {
		this.touched = touched;
	}

	public int getTopX() {
		return topX;
	}

	public void setTopX(int topX) {
		if (isxLeftLimitSet() && isxRightLimitSet()) {
			if (topX <= xRightLimit && topX >= xLeftLimit) {
				this.topX = topX;
			}
		} else {
			this.topX = topX;
		}
	}

	public int getTopY() {
		return topY;
	}

	public void setTopY(int topY) {
		this.topY = topY;
	}

	public int getBottomX() {
		return bottomX;
	}

	public void setBottomX(int bottomX) {
		if (isxLeftLimitSet() && isxRightLimitSet()) {
			if (bottomX <= xRightLimit && bottomX >= xLeftLimit) {
				this.bottomX = bottomX;
			}
		} else {
			this.bottomX = bottomX;
		}
	}

	public int getBottomY() {
		return bottomY;
	}

	public void setBottomY(int bottomY) {
		this.bottomY = bottomY;
	}

	public void draw(Canvas canvas, String[] xyValues, Rect mScreenLimits, double screenPointForKey) {

		setLastCrossedX((int) screenPointForKey);

		if (mScreen.right == 0) {
			mScreen.set(mScreenLimits);
		}

		if (topX > mScreenLimits.right) {
			topX = mScreenLimits.right;
		}
		mRect.set(topX, topY, bottomX, bottomY);		
//		mPaint.setColor(Color.RED);
//
//		canvas.drawLine(topX, topY, topX, bottomY, mPaint);
//
//		mPaint.setColor(Color.rgb(255, 153, 0));
//
//		mPaint.setTextAlign(Paint.Align.CENTER);
//
//		float maxLength = 0f;
//		for (int i = 0; i < xyValues.length; i++) {
//			if (xyValues[i] != null && maxLength < mPaint.measureText(xyValues[i])) {
//				maxLength = mPaint.measureText(xyValues[i]);
//			}
//		}
//
//		float maxVerticalLength = xyValues.length * 16;
//
//		int left = (int) mRect.left;
//		if (left < (maxLength / 2) + mScreenLimits.left) {
//			left = (int) ((maxLength / 2) + mScreenLimits.left);
//		}
//
//		if (left > mScreenLimits.right - (maxLength / 2)) {
//			left = (int) (mScreenLimits.right - (maxLength / 2));
//		}
//
//		Rect dst = new Rect((int) (left - maxLength / 2 - 10), (int) (mRect.top - 45), (int) (left + maxLength / 2 + 10), (int) (mRect.top
//				+ maxVerticalLength / 2 + 40));
//		mPopupBoxNinePatchDrawable.setBounds(dst);
//		mPopupBoxNinePatchDrawable.draw(canvas);
//
//		int yDistBetweenTexts = 15;
//		if (xyValues.length > 0) {
//			if (xyValues[0] != null) {
//				canvas.drawText(xyValues[0], left, mRect.top, mPaint);
//			}
//		}
//
//		for (int i = 1; i < xyValues.length; i = i + 2) {
//			if (xyValues[i] != null) {
//				canvas.drawText(xyValues[i], left, mRect.top + yDistBetweenTexts * ((i / 2) + 1), mPaint);
//			}
//		}
		
		
		
		mPaint.setColor(Color.rgb(153, 255, 255));
		mPaint.setStrokeWidth(2.0f);
		mPaint.setPathEffect(new DashPathEffect(new float[] {5,3}, 0));
		

		canvas.drawLine(topX, topY, topX, bottomY, mPaint);
		
		mPaint.reset();	
        
		float maxTextLength = 0f;
		float maxTextHeight = 0f;
		float maxVerticalLength =0f;
		float yDistBetweenTexts = 15.0f;
		Rect textBounds = new Rect(0,0,0,0);
		for (int i = 0; i < xyValues.length; i++) {
			if (xyValues[i] != null){
				mPaint.getTextBounds(xyValues[i], 0, xyValues[i].length(), textBounds);
				if(maxTextLength < textBounds.width()){
					maxTextLength = textBounds.width();
				}
				if(maxTextHeight < textBounds.height()){
					maxTextHeight = textBounds.height();
				}
			}
		}

		yDistBetweenTexts = (float) (maxTextHeight/6.0);
		maxVerticalLength = ((xyValues.length/2)+1) * maxTextHeight + ((xyValues.length/2)+2)*yDistBetweenTexts;

		int left = (int) mRect.left;
		if (left < (maxTextLength / 2) + mScreenLimits.left) {
			left = (int) ((maxTextLength / 2) + mScreenLimits.left);
		}

		if (left > mScreenLimits.right - (maxTextLength / 2)) {
			left = (int) (mScreenLimits.right - (maxTextLength / 2));
		}
		
		Rect dst = new Rect((int) (left - maxTextLength / 2 - 5), (int) Math.ceil(mRect.top - maxVerticalLength), (int) (left + maxTextLength / 2 + 5), (int) mRect.top);		
		mPaint.setColor(Color.BLACK);
		canvas.drawRect(dst, mPaint);
		
		//mPaint.setColor(Color.rgb(255, 153, 0));
		
		mPaint.setColor(Color.rgb(153, 255, 255));
		
		mPaint.setTextAlign(Paint.Align.CENTER);	
		
		
		for (int i = xyValues.length-1; i > 0; i = i - 2) {
			if (xyValues[i] != null) {
				canvas.drawText(xyValues[i], left, mRect.top - maxVerticalLength + (yDistBetweenTexts+maxTextHeight) * ((i / 2) + 1)+maxTextHeight + yDistBetweenTexts, mPaint);
			}
		}
		
		if (xyValues.length > 0) {
			if (xyValues[0] != null) {
				canvas.drawText(xyValues[0], left,  (mRect.top - maxVerticalLength + maxTextHeight + yDistBetweenTexts), mPaint);
			}
		}

	}

	public void handleTouch(int eventX, int eventY) {
		if ((eventX >= (topX - 5) && eventX <= (bottomX + 5)) && (eventY >= topY && eventY <= bottomY)) {
			setTouched(true);
			Log.d(TAG, "Line is touched ");
		} else {
			setTouched(false);
		}
	}

	/**
	 * @return the lastCrossedX
	 */
	public double getLastCrossedX() {
		return lastCrossedX;
	}

	/**
	 * @param lastCrossedX
	 *            the lastCrossedX to set
	 */
	public void setLastCrossedX(int lastCrossedX) {
		this.lastCrossedX = lastCrossedX;
	}

	public void jumpToNearestPoint() {
		setTopX((int) lastCrossedX);
		setBottomX((int) lastCrossedX);

	}

	public int getxRightLimit() {
		return xRightLimit;
	}

	public void setxRightLimit(int xRightLimit) {
		if (!isxRightLimitSet()) {
			this.xRightLimit = xRightLimit;
		}
		setxRightLimitSet(true);
	}

	public void setxLeftLimit(int xLeftLimit) {
		if (!isxLeftLimitSet()) {
			this.xLeftLimit = xLeftLimit;
		}
		setxLeftLimitSet(true);

	}

	public boolean isxLeftLimitSet() {
		return xLeftLimitSet;
	}

	public void setxLeftLimitSet(boolean xLeftLimitSet) {
		this.xLeftLimitSet = xLeftLimitSet;
	}

	public boolean isxRightLimitSet() {
		return xRightLimitSet;
	}

	public void setxRightLimitSet(boolean xRightLimitSet) {
		this.xRightLimitSet = xRightLimitSet;
	}

	/**
	 * @return the firstTimeTouched
	 */
	public boolean isFirstTimeTouched() {
		return firstTimeTouched;
	}

	/**
	 * @param firstTimeTouched the firstTimeTouched to set
	 */
	public void setFirstTimeTouched(boolean firstTimeTouched) {
		this.firstTimeTouched = firstTimeTouched;
	}
}
